home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 1
/
Gold Medal Software Volume 1 (Gold Medal) (1994).iso
/
graphics
/
povsrc20.arj
/
SOURCE
/
PLANES.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-29
|
6KB
|
219 lines
/****************************************************************************
* planes.c
*
* This module implements functions that manipulate planes.
*
* from Persistence of Vision Raytracer
* Copyright 1993 Persistence of Vision Team
*---------------------------------------------------------------------------
* NOTICE: This source code file is provided so that users may experiment
* with enhancements to POV-Ray and to port the software to platforms other
* than those supported by the POV-Ray Team. There are strict rules under
* which you are permitted to use this file. The rules are in the file
* named POVLEGAL.DOC which should be distributed with this file. If
* POVLEGAL.DOC is not available or for more info please contact the POV-Ray
* Team Coordinator by leaving a message in CompuServe's Graphics Developer's
* Forum. The latest version of POV-Ray may be found there as well.
*
* This program is based on the popular DKB raytracer version 2.12.
* DKBTrace was originally written by David K. Buck.
* DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
*
*****************************************************************************/
#include "frame.h"
#include "vector.h"
#include "povproto.h"
METHODS Plane_Methods =
{
All_Plane_Intersections,
Inside_Plane, Plane_Normal,
Copy_Plane,
Translate_Plane, Rotate_Plane,
Scale_Plane, Transform_Plane, Invert_Plane, Destroy_Plane
};
extern RAY *CM_Ray;
extern long Ray_Plane_Tests, Ray_Plane_Tests_Succeeded;
#ifndef Plane_Tolerance
#define Plane_Tolerance 1.0e-8
#endif
int All_Plane_Intersections (Object, Ray, Depth_Stack)
OBJECT *Object;
RAY *Ray;
ISTACK *Depth_Stack;
{
DBL Depth;
VECTOR IPoint;
if (Intersect_Plane (Ray, (PLANE *)Object, &Depth))
if (Depth > Plane_Tolerance)
{
VScale (IPoint, Ray -> Direction, Depth);
VAddEq (IPoint, Ray -> Initial);
if (Point_In_Clip (&IPoint, Object->Clip))
{
push_entry(Depth,IPoint,Object,Depth_Stack);
return (TRUE);
}
}
return (FALSE);
}
int Intersect_Plane (Ray, Plane, Depth)
RAY *Ray;
PLANE *Plane;
DBL *Depth;
{
DBL NormalDotOrigin, NormalDotDirection;
Ray_Plane_Tests++;
if (Ray == CM_Ray)
{
VDot (NormalDotDirection, Plane->Normal_Vector, Ray->Direction);
if ((NormalDotDirection < Plane_Tolerance) &&
(NormalDotDirection > -Plane_Tolerance))
return (FALSE);
if (!Plane->CMCached)
{
VDot (Plane->CMNormDotOrigin, Plane->Normal_Vector, Ray->Initial);
Plane->CMNormDotOrigin += Plane->Distance;
Plane->CMNormDotOrigin *= -1.0;
Plane->CMCached = TRUE;
}
*Depth = Plane->CMNormDotOrigin / NormalDotDirection;
if ((*Depth >= Plane_Tolerance) && (*Depth <= Max_Distance))
{
Ray_Plane_Tests_Succeeded++;
return (TRUE);
}
else
return (FALSE);
}
else
{
VDot (NormalDotDirection, Plane->Normal_Vector, Ray->Direction);
if ((NormalDotDirection < Plane_Tolerance) &&
(NormalDotDirection > -Plane_Tolerance))
return (FALSE);
VDot (NormalDotOrigin, Plane->Normal_Vector, Ray->Initial);
NormalDotOrigin += Plane->Distance;
NormalDotOrigin *= -1.0;
*Depth = NormalDotOrigin / NormalDotDirection;
if ((*Depth >= Plane_Tolerance) && (*Depth <= Max_Distance))
{
Ray_Plane_Tests_Succeeded++;
return (TRUE);
}
else
return (FALSE);
}
}
int Inside_Plane (IPoint, Object)
VECTOR *IPoint;
OBJECT *Object;
{
DBL Temp;
VDot (Temp, *IPoint, ((PLANE *)Object)->Normal_Vector);
return ((Temp + ((PLANE *)Object)->Distance) <= Plane_Tolerance);
}
void Plane_Normal (Result, Object, IPoint)
OBJECT *Object;
VECTOR *Result, *IPoint;
{
*Result = ((PLANE *)Object)->Normal_Vector;
}
void Translate_Plane (Object, Vector)
OBJECT *Object;
VECTOR *Vector;
{
VECTOR Translation;
VEvaluate (Translation, ((PLANE *)Object)->Normal_Vector, *Vector);
((PLANE *)Object)->Distance -= Translation.x + Translation.y + Translation.z;
}
void Rotate_Plane (Object, Vector)
OBJECT *Object;
VECTOR *Vector;
{
TRANSFORM Trans;
Compute_Rotation_Transform (&Trans, Vector);
Transform_Plane (Object, &Trans);
}
void Scale_Plane (Object, Vector)
OBJECT *Object;
VECTOR *Vector;
{
DBL Length;
PLANE *Plane = (PLANE *) Object;
VDivEq(Plane->Normal_Vector, *Vector);
VLength(Length, ((PLANE *)Object)->Normal_Vector);
VScaleEq (((PLANE *)Object)->Normal_Vector, 1.0 / Length);
((PLANE *)Object)->Distance /= Length;
}
void Invert_Plane (Object)
OBJECT *Object;
{
VScaleEq (((PLANE *) Object)->Normal_Vector, -1.0);
((PLANE *) Object)->Distance *= -1.0;
}
PLANE *Create_Plane()
{
PLANE *New;
if ((New = (PLANE *) malloc (sizeof (PLANE))) == NULL)
MAError ("plane");
INIT_OBJECT_FIELDS(New,PLANE_OBJECT,&Plane_Methods)
Make_Vector (&(New -> Normal_Vector), 0.0, 1.0, 0.0);
New -> Distance = 0.0;
New -> CMNormDotOrigin = 0.0;
New -> CMCached = 0;
return (New);
}
void *Copy_Plane (Object)
OBJECT *Object;
{
PLANE *New;
New = Create_Plane ();
*New = * ((PLANE *)Object);
return (New);
}
void Transform_Plane (Object, Trans)
OBJECT *Object;
TRANSFORM *Trans;
{
MTransPoint (&((PLANE *) Object)->Normal_Vector,
&((PLANE *) Object)->Normal_Vector, Trans);
}
void Destroy_Plane (Object)
OBJECT *Object;
{
free (Object);
}